#include <unistd.h>
#include "stdio.h"
#include "ohos_init.h"
#include "cmsis_os2.h"

#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_i2c.h"
#include "iot_adc.h"
#include "oledfont.h"
#include "iot_pwm.h"
#include "ohos_errno.h"

#include "OLED_init.h"

#define LED_INTERVAL_TIME_US 15000
#define LED_TASK_STACK_SIZE 1024
#define LED_TASK_PRIO 25

#define RET_OK 0
#define RET_FAIL 1

static unsigned int PressOled_ok=1;
static unsigned int PressLed_ok=1;

static unsigned int lastTickCount = 0;

static unsigned int Index=1;
static unsigned int Manual=0;
static unsigned int Automatic=0;

//LED亮度
unsigned short duty = 0;
unsigned int freq = 15000;
static char plus_status = 1;
static char reduce_status = 1;

osMutexId_t mutex_id;
uint32_t timerExec;

static unsigned int led_Level = 0;

static unsigned int operation_begin = 0;
static unsigned int operation_plus = 0;

static char time[] ="00:00";

static unsigned int Press_PlusOK = 1;
static unsigned int Press_BeginOK = 0;


/**
 * @brief 倒计时 
 * 
 */
void CountDown(void *arg)
{
    printf("CountDown!\r\n");
    //uint32_t t = (uint32_t)arg;
    led_Level ^= 1;
    IoTGpioSetOutputVal(IOT_GPIO_IO_GPIO_9, led_Level);
    time[0]='0';
    time[1]='0';
    time[3]='0';
    time[4]='0';
    printf("%s\r\n",time);
    Press_PlusOK=1;
    
}

/**
 * @brief 倒计时开始
 * 
 */
void CountDownStart(void)
{
    while(1)
    {
        usleep(15000);
        if(operation_begin == 1)
    {
        //初始化主板灯引脚
        IoTGpioInit(IOT_GPIO_IO_GPIO_9);
        IoTIoSetFunc(IOT_GPIO_IO_GPIO_9, IOT_IO_FUNC_GPIO_9_GPIO);
        IoTGpioSetDir(IOT_GPIO_IO_GPIO_9, IOT_GPIO_DIR_OUT);
        IoTGpioSetOutputVal(IOT_GPIO_IO_GPIO_9, IOT_GPIO_VALUE0);

        printf("operation_begin ! \r\n");
        osTimerId_t timerId;
        osStatus_t status;

        timerExec = 1U;
        printf("Pre timer create! \r\n");
        timerId = osTimerNew((osTimerFunc_t)CountDown,osTimerOnce, &timerExec, NULL);
        if(timerId != NULL)
        {
            uint32_t delay;
            printf("timer create\r\n ");
            delay = (int)(((time[4]-'0')+(time[3]-'0')*10+(time[1]-'0')*60+(time[0]-'0')*600)*100);
            printf("delay = %u \r\n",delay);
            //delay = 500U;
            status = osTimerStart(timerId,delay);
            if(status != osOK)
            {
                printf("Falied to start timer! \r\n");
            }
        }
        else
        {
            printf("Falied to create timer!\r\n");
        }
        operation_begin = 0;
    }
     
 } 
}



/**
 * @brief 加时 
 * 
 */
void OperationPlus(void)
{
    printf("OperationPlus \r\n");
    if(time[4] == '9')
    {
        time[3] += 1;
        time[4] = '0';
    }
    else
    {
        time[4] += 1;
    }
    if(time[3] == '6')
    {
        time[1] += 1;
        time[3] = '0';
    }
    if(time[1] == '9')
    {
        if(time[0] == '9')
        {
            time[4] = '0';
            time[3] = '0';
            time[1] = '0';
            time[0] = '0';
        }
        else
        {
            time[0] += 1;
            time[1] = '0';
        }
       
    }
}


/**
 * @brief 操作判断
 */
void OperationCheck(void)
{
    /*if(operation_begin == 1)
    {
       
    }*/
     if(operation_plus == 1)
    {
        printf("OperationCheck operation_plus = %u \r\n",operation_plus);
        OperationPlus();
        operation_plus = 0;
    }
}

void GpioTimerPressedIsrFunc(char *arg)
{
    (void)arg;
    
    //电压控制
    float voltage;
    unsigned int ret;
    unsigned short val;
    
     //消除按键抖动
    unsigned int tickCount = osKernelGetTickCount();
    unsigned int count = tickCount - lastTickCount;
    lastTickCount = tickCount;

     //获取ADC采集值
    ret = IoTAdcRead(IOT_ADC_CHANNEL_2, &val, IOT_ADC_EQU_MODEL_8, IOT_ADC_CUR_BAIS_DEFAULT, 256);

    if (ret != EC_SUCCESS)
    {
        printf("Failed to read adc! Err code = %u\n", ret);
    }
	
    //将ADC采集值转换成电压值
    voltage = IOTAdcConvertToVoltage(val);

    if(count>50)
    {
        if(voltage<1) //减
        {
          operation_begin = 1;
          operation_plus = 0;
        }
        else if(voltage>=1&&voltage<2)  //加
        {
           operation_plus = 1;
           operation_begin = 0;
            OperationCheck();
           Press_PlusOK = 1;
          
        }
    }
    printf("voltge:%.2f \r\n",voltage);
    printf(" operation_plus = %u \r\n",operation_plus);
    printf(" operation_begin = %u \r\n", operation_begin);
    printf("Press_PlusOK = %u \r\n",Press_PlusOK);
    printf("time = %s \r\n",time);
	
   
}


/**
 * @brief  定时时间加减按键
 */
 void *OledTimerpressTask(const char *arg)
{
    (void)arg;

    unsigned int interrupt;
    //初始化GPIO5引脚
    IoTGpioInit(IOT_GPIO_IO_GPIO_5);
    IoTIoSetFunc(IOT_GPIO_IO_GPIO_5, IOT_IO_FUNC_GPIO_5_GPIO);
    IoTIoSetPull(IOT_GPIO_IO_GPIO_5, IOT_IO_PULL_UP);
    IoTGpioSetDir(IOT_GPIO_IO_GPIO_5, IOT_GPIO_DIR_IN);


    //设置GPIO5中断
    interrupt=IoTGpioRegisterIsrFunc(IOT_GPIO_IO_GPIO_5, IOT_INT_TYPE_EDGE,
                                 IOT_GPIO_EDGE_FALL_LEVEL_LOW, GpioTimerPressedIsrFunc, NULL);
    if (interrupt != RET_OK)
    {
        printf("===== ERROR ======gpio -> hi_gpio_register_isr_function ret:%u\r\n", interrupt);
    }
	

    return NULL;
}

/**
 * @brief Oled主任务函数
 */ 
 void TimerTask(void)
{
   
    while(1)
    {
        usleep(15000);
        if(Press_PlusOK == 1)
        {
             //初始化I2C0 配置，速率为400K
	        I2coInit();
            //oled初始化配置
            OledInit();
            printf("TimerTask \r \n");
	        //显示字符串
            OledShowString(40,30,time,16);
	        OledRefresh();
            Press_PlusOK = 0;
	        //删除任务
	        //osThreadTerminate(g_oledTaskID);
        }
    }
}

/**
 * @brief 手动线程
 * 
 */
void Thread_Manual(void)
{
    void *LedpressTask(const char *arg);
    void pwmTask(void);
    
    osThreadAttr_t attr_LedpressTask;
    attr_LedpressTask.name = "LedpressTask";
    attr_LedpressTask.attr_bits = 0U;
    attr_LedpressTask.cb_mem = NULL;
    attr_LedpressTask.cb_size = 0U;
    attr_LedpressTask.stack_mem = NULL;
    attr_LedpressTask.stack_size = LED_TASK_STACK_SIZE;
    attr_LedpressTask.priority = LED_TASK_PRIO;

    osThreadAttr_t attr_pwm;
    attr_pwm.name="pwmTask";
    attr_pwm.attr_bits = 0U;
    attr_pwm.cb_mem = NULL;
    attr_pwm.cb_size = 0U;
    attr_pwm.stack_mem = NULL;
    attr_pwm.stack_size = LED_TASK_STACK_SIZE*4;
    attr_pwm.priority = LED_TASK_PRIO;
    if(osThreadNew((osThreadFunc_t)LedpressTask,NULL,&attr_LedpressTask)==NULL)
    {
        printf("Falied to create LedpressTask!\n");
    }
    if(osThreadNew((osThreadFunc_t)pwmTask,NULL,&attr_pwm)==NULL)
    {
        printf("Falied to create pwmTask!\n");
     }
        
    
}

/**
 * @brief 自动线程
 * 
 */
void Thread_Automatic(void)
{
    void TimerTask(void);
    void *OledTimerpressTask(const char *arg);
    void CountDownStart(void);
    osThreadAttr_t attr_Auto;
    attr_Auto.name = "TimerTask";
    attr_Auto.attr_bits = 0U;
    attr_Auto.cb_mem = NULL;
    attr_Auto.cb_size = 0U;
    attr_Auto.stack_mem = NULL;
    attr_Auto.stack_size = OLED_TASK_STACK_SIZE;
    attr_Auto.priority = OLED_TASK_PRIO;

    osThreadAttr_t attr_press;
    attr_press.name = "OledTimerpressTask";
    attr_press.attr_bits = 0U;
    attr_press.cb_mem = NULL;
    attr_press.cb_size = 0U;
    attr_press.stack_mem = NULL;
    attr_press.stack_size = OLED_TASK_STACK_SIZE;
    attr_press.priority = OLED_TASK_PRIO;

    osThreadAttr_t attr_timer;
    attr_timer.name = "CountDownStartTask";
    attr_timer.attr_bits = 0U;
    attr_timer.cb_mem = NULL;
    attr_timer.cb_size = 0U;
    attr_timer.stack_mem = NULL;
    attr_timer.stack_size = OLED_TASK_STACK_SIZE;
    attr_timer.priority = OLED_TASK_PRIO;

               
    if( osThreadNew((osThreadFunc_t)TimerTask, NULL, &attr_Auto) == NULL)
    {
        printf("Failed to create TimerTask! \n");
    }

	if (osThreadNew((osThreadFunc_t)OledTimerpressTask, NULL, &attr_press)== NULL)
	{
        printf(" Falied to create OledpressTask!\n");
    }

    if(osThreadNew((osThreadFunc_t)CountDownStart,NULL,&attr_timer) == NULL)
    {
        printf("Falied to create CountDownStart! \r\n");
    } 
        
}


/**
 * @brief 主页
 */
void OledIndex(void)
{
    //初始化I2C0 配置，速率为400K
	I2coInit();

	//oled初始化配置
    OledInit();

	//显示字符串
	OledShowString(30,10,"Automatic",16);
	OledShowString(20,40,"Manual",16);
	OledRefresh();
}

/**
 * @brief 手动控制 
 */
void OledManual(void)
{
    //初始化I2C0 配置，速率为400K
    I2coInit();

    //oled初始化配置
    OledInit();

    //显示字符串
	OledShowString(20,24,"de",16);
	OledShowString(50,24,"add",16);
	OledRefresh();
}

/**
 * @brief  灯光可操作判断
 * 
 */
void StatusCheck(void)
{
    if(duty==0)
    {
        reduce_status=1;
        plus_status=0;
    }
    else if(duty>=99)
    {
        reduce_status=0;
        plus_status=1;
    }else if(duty>0&&duty<99)
    {
        reduce_status=1;
        plus_status=1;
    }
}

/**
 * @brief  灯光按键函数
 * 
 */
void GpioLedPressedIsrFunc(char *arg)
{
    (void)arg;
    
    //电压控制
    float voltage;
    unsigned int ret;
    unsigned short val;
    
     //消除按键抖动
    unsigned int tickCount = osKernelGetTickCount();
    unsigned int count = tickCount - lastTickCount;
    lastTickCount = tickCount;

     //获取ADC采集值
    ret = IoTAdcRead(IOT_ADC_CHANNEL_2, &val, IOT_ADC_EQU_MODEL_8, IOT_ADC_CUR_BAIS_DEFAULT, 256);

    if (ret != EC_SUCCESS)
    {
        printf("Failed to read adc! Err code = %u\n", ret);
    }
    //将ADC采集值转换成电压值
    voltage = IOTAdcConvertToVoltage(val);

    //LED操作判断
    StatusCheck();
    if(count>50)
    {
        if(voltage<1) //变暗
        //printf("voltage:%.3fV \r\n", voltage);
        {
            if(reduce_status)
            {
                PressLed_ok=1;
                duty+=20;
            }
            printf("an \r\n");
            printf("voltage:%.3fV  0V\r\n",voltage);
            printf("duty:%d \r\n",duty);
            printf("PressLed_ok: %u \r\n",PressLed_ok);
        }
        else if(voltage>=1&&voltage<2)  //变亮
        {
            if(plus_status)
            {
                PressLed_ok=1;
                duty-=20;
            }
            printf("liang \r\n");
            printf("voltage:%.3fV  1V\r\n",voltage);
            printf("duty:%d \r\n",duty);
            printf("PressLed_ok: %u \r\n",PressLed_ok);
        }
    }
   
}
/**
 * @brief 灯光按键中断任务
 * 
 */

void *LedpressTask(const char *arg)
{ 
        //usleep(LED_INTERVAL_TIME_US);
            (void)arg;

            unsigned int interrupt;

            //初始化GPIO9引脚
            IoTGpioInit(IOT_GPIO_IO_GPIO_9);
            IoTIoSetFunc(IOT_GPIO_IO_GPIO_9, IOT_IO_FUNC_GPIO_9_PWM0_OUT);
            IoTGpioSetDir(IOT_GPIO_IO_GPIO_9, IOT_GPIO_DIR_OUT);

            //初始化GPIO5引脚
            IoTGpioInit(IOT_GPIO_IO_GPIO_5);
            IoTIoSetFunc(IOT_GPIO_IO_GPIO_5, IOT_IO_FUNC_GPIO_5_GPIO);
            IoTIoSetPull(IOT_GPIO_IO_GPIO_5, IOT_IO_PULL_UP);
            IoTGpioSetDir(IOT_GPIO_IO_GPIO_5, IOT_GPIO_DIR_IN);

            //初始化PWM引脚
            IoTPwmInit(IOT_PWM_PORT_PWM0);

            //设置GPIO5中断
            interrupt=IoTGpioRegisterIsrFunc(IOT_GPIO_IO_GPIO_5, IOT_INT_TYPE_EDGE,
                                        IOT_GPIO_EDGE_FALL_LEVEL_LOW, GpioLedPressedIsrFunc, NULL);
            if (interrupt != RET_OK)
            {
             printf("===== ERROR ======gpio -> hi_gpio_register_isr_function ret:%u\r\n", interrupt);
            }

    return NULL;
}

/**
 * @brief 灯光调节线程任务
 * 
 */
void pwmTask(void)
{
    printf("IoTPwmStart \r\n");
    while(1)
    { 
        usleep(LED_INTERVAL_TIME_US);
        if(PressLed_ok==1)
        {
            if(Manual==1)
            {
                printf("MP\r\n");
                
                if(duty==100)
                {
                    IoTPwmStart(IOT_PWM_PORT_PWM0, 99, freq);
                    PressLed_ok=0;
                }
                else
                {
                    IoTPwmStart(IOT_PWM_PORT_PWM0, duty, freq);
                    PressLed_ok=0;
                }
            }
        }
    }
}


/**
 * @brief  模式切换
 */
void ModeControlTask(void)
{
	while(1)
	{
		usleep(15000);
		if(PressOled_ok==1)
		{
			if(Index==1)
			{
                //osMutexAcquire(mutex_id, osWaitForever);
				OledIndex();
				PressOled_ok=0;
			}
			if(Manual==1)
			{
                //osMutexAcquire(mutex_id, osWaitForever);
				OledManual();
                Thread_Manual();
                /*osThreadAttr_t attr_LedpressTask;
                attr_LedpressTask.name = "LedpressTask";
                attr_LedpressTask.attr_bits = 0U;
                attr_LedpressTask.cb_mem = NULL;
                attr_LedpressTask.cb_size = 0U;
                attr_LedpressTask.stack_mem = NULL;
                attr_LedpressTask.stack_size = LED_TASK_STACK_SIZE;
                attr_LedpressTask.priority = LED_TASK_PRIO;

                osThreadAttr_t attr_pwm;
                attr_pwm.name="pwmTask";
                attr_pwm.attr_bits = 0U;
                attr_pwm.cb_mem = NULL;
                attr_pwm.cb_size = 0U;
                attr_pwm.stack_mem = NULL;
                attr_pwm.stack_size = LED_TASK_STACK_SIZE*4;
                attr_pwm.priority = LED_TASK_PRIO;
                if(osThreadNew((osThreadFunc_t)LedpressTask,NULL,&attr_LedpressTask)==NULL)
                {
                    printf("Falied to create LedpressTask!\n");
                }
                if(osThreadNew((osThreadFunc_t)pwmTask,NULL,&attr_pwm)==NULL)
                {
                    printf("Falied to create pwmTask!\n");
                }*/
               
                PressOled_ok=0;
            }
            if(Automatic==1)
            {
                //osMutexAcquire(mutex_id, osWaitForever);
                Thread_Automatic();
                /*osThreadAttr_t attr_Auto;
                attr_Auto.name = "TimerTask";
                attr_Auto.attr_bits = 0U;
                attr_Auto.cb_mem = NULL;
                attr_Auto.cb_size = 0U;
                attr_Auto.stack_mem = NULL;
                attr_Auto.stack_size = OLED_TASK_STACK_SIZE;
                attr_Auto.priority = OLED_TASK_PRIO;

                osThreadAttr_t attr_press;
                attr_press.name = "OledTimerpressTask";
                attr_press.attr_bits = 0U;
                attr_press.cb_mem = NULL;
                attr_press.cb_size = 0U;
                attr_press.stack_mem = NULL;
                attr_press.stack_size = OLED_TASK_STACK_SIZE;
                attr_press.priority = OLED_TASK_PRIO;

                osThreadAttr_t attr_timer;
                attr_timer.name = "CountDownStartTask";
                attr_timer.attr_bits = 0U;
                attr_timer.cb_mem = NULL;
                attr_timer.cb_size = 0U;
                attr_timer.stack_mem = NULL;
                attr_timer.stack_size = OLED_TASK_STACK_SIZE;
                attr_timer.priority = OLED_TASK_PRIO;

               
                if( osThreadNew((osThreadFunc_t)TimerTask, NULL, &attr_Auto) == NULL)
                {
                    printf("Failed to create TimerTask! \n");
                }

	            if (osThreadNew((osThreadFunc_t)OledTimerpressTask, NULL, &attr_press)== NULL)
	            {
                    printf(" Falied to create OledpressTask!\n");
                }

                if(osThreadNew((osThreadFunc_t)CountDownStart,NULL,&attr_timer) == NULL)
                {
                     printf("Falied to create CountDownStart! \r\n");
                }*/
                 PressOled_ok=0;
            }
		}
	}

}

/**
 * @brief 模式切换按键函数
 * 
 * @param arg 
 */
void GpioOledPressedIsrFunc(char *arg)
{
    (void)arg;
    
    //电压控制
    float voltage;
    unsigned int ret;
    unsigned short val;
    
     //消除按键抖动
    unsigned int tickCount = osKernelGetTickCount();
    unsigned int count = tickCount - lastTickCount;
    lastTickCount = tickCount;

     //获取ADC采集值
    ret = IoTAdcRead(IOT_ADC_CHANNEL_3, &val, IOT_ADC_EQU_MODEL_8, IOT_ADC_CUR_BAIS_DEFAULT, 256);

    if (ret != EC_SUCCESS)
    {
        printf("Failed to read adc! Err code = %u\n", ret);
    }
	
    //将ADC采集值转换成电压值
    voltage = IOTAdcConvertToVoltage(val);

    if(count>50)
    {
        if(Index==1)
        {
            
            if(voltage<1) //自动控制
            {
                Index=0;
		        Manual=0;
                Automatic=1;
		        PressOled_ok=1;
            }
            else if(voltage>=1&&voltage<2)  //手动控制页面
            {
                Index=0;
		        Manual=1;
                Automatic=0;
		        PressOled_ok=1;
            }
        }else if(Manual==1)
        {
             if(voltage<1) //回到主页
            {
                Index=1;
		        Manual=0;
                Automatic=0;
		        PressOled_ok=1;
            }
            else if(voltage>=1&&voltage<2)  //手动控制页面
            {
                Index=0;
		        Manual=1;
                Automatic=0;
		        PressOled_ok=1;
            }
        }else if(Automatic==1)
        {
             if(voltage<1) 
            {
                Index=0;
		        Manual=0;
                Automatic=1;
		        PressOled_ok=1;
            }
            else if(voltage>=1&&voltage<2)  //主页
            {
                Index=1;
		        Manual=0;
                Automatic=0;
		        PressOled_ok=1;
            }
        }
        
    }
    printf("voltge:%.2f \r\n",voltage);
	printf("PressOled_OK:%u \r\n",PressOled_ok);
    printf("Manual:%u \r\n",Manual);
    printf("Automatic:%u \r\n",Automatic);
	
   
}


//模式切换按键线程
static void *OledpressTask(const char *arg)
{
    (void)arg;

    unsigned int interrupt;
    //初始化GPIO7引脚
    IoTGpioInit(IOT_GPIO_IO_GPIO_7);
    IoTIoSetFunc(IOT_GPIO_IO_GPIO_7, IOT_IO_FUNC_GPIO_7_GPIO);
    IoTIoSetPull(IOT_GPIO_IO_GPIO_7, IOT_IO_PULL_UP);
    IoTGpioSetDir(IOT_GPIO_IO_GPIO_7, IOT_GPIO_DIR_IN);


    //设置GPIO7中断
    interrupt=IoTGpioRegisterIsrFunc(IOT_GPIO_IO_GPIO_7, IOT_INT_TYPE_EDGE,
                                 IOT_GPIO_EDGE_FALL_LEVEL_LOW, GpioOledPressedIsrFunc, NULL);
    if (interrupt != RET_OK)
    {
        printf("===== ERROR ======gpio -> hi_gpio_register_isr_function ret:%u\r\n", interrupt);
    }
	

    return NULL;
}




static void OledIndexEntry(void)
{
	
    osThreadAttr_t attr;
    attr.name = "OledpressTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 1024;
    attr.priority = 25;

    osThreadAttr_t attr_control;
    attr_control.name="ModeControlTask";
    attr_control.attr_bits = 0U;
    attr_control.cb_mem = NULL;
    attr_control.cb_size = 0U;
    attr_control.stack_mem = NULL;
    attr_control.stack_size = 1024*4;
    attr_control.priority = 25;

    if (osThreadNew((osThreadFunc_t)OledpressTask, NULL, &attr) == NULL)
    {
        
        printf(" Falied to create OledpressTask!\n");
    }

   
    if(osThreadNew((osThreadFunc_t)ModeControlTask,NULL,&attr_control)==NULL)
    {
        printf("Falied to create ModeControlTask!\n");
    }

    mutex_id = osMutexNew(NULL);
    if (mutex_id == NULL)
    {
      	printf("create Mutex failed!\n");
    }

   
    
}

APP_FEATURE_INIT(OledIndexEntry);

